<template>
  <div class="card-box" :style="GT_style">
    <Handler
      :mode="GT_mode"
      :position="GT_position"
      :expand="GT_isExpand"
      :compBoxInfo="GT_compBoxInfo"
    >
    </Handler>
    <div class="card-body">
      <slot></slot>
    </div>
  </div>
</template>

<script lang="ts">
import { Tsrv, T_srv, ts, ifs, vue } from '@/services';
import Handler from './Handler.vue';

@T_srv.comp({
  components: {
    Handler
  }
})
export default class oCardBox extends vue {
  // 默认不打开
  @T_srv.prop({ type: Boolean, default: false }) isExpand: boolean;

  @T_srv.prop({ type: Number, required: false }) width: number;

  @T_srv.prop({ type: Number, required: false }) height: number;

  @T_srv.prop({ type: Boolean, required: false, default: false })
  disabled: boolean;

  // 父组件compBoxInfo
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  // box 位置
  @T_srv.prop({
    type: String,
    default: 'right',
    validator: val => {
      return ['top', 'right', 'bottom', 'left'].includes(val);
    }
  })
  position: string;

  private G_compName: string = 'oCardBox';

  private GT_isExpand: boolean;

  private G_compID: string;

  private GT_compBox: ifs.I_compBox;

  private GT_style: any = {};

  private GT_position: string;

  private GT_mode: string;

  private GT_placement: string;

  private GT_compBoxInfo: ifs.I_compBoxInfo;

  @T_srv.watch('isExpand')
  onIsExpandChange(val) {
    this.toggleHandler(val);
  }

  @T_srv.watch('disabled')
  onDisabled(val) {
    if (val === true) {
      this.closeCardBox();
    }
  }

  created() {
    this.G_compID = Tsrv.utils.getGUID();
    this.GT_isExpand = this.isExpand;
    // 如果外部有传入组件信息
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox = new ts.T_compBox(this.G_compID); // 使用本地实例
    } else {
      this.G_compID = this.compBoxInfo.compID;
      this.GT_compBox = this.compBoxInfo.TcompBox;
    }
    this.GT_compBoxInfo = { compID: this.G_compID, TcompBox: this.GT_compBox };
    this.boxStyle();
  }

  mounted() {
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
  }

  destroyed() {
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);

    /* 最终应用组件销毁 */
    /* this.GT_compBox.removeCompMergeName(this.G_compID, 'devBom','funName'); */

    /* 如果父组件传入的compBoxInfo则删除本文件产生的引用,反之是本组件产生的ID统一删除 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
  }

  private getStyle(): any {
    const self = this;
    const style: any = {};
    if (self.GT_placement) {
      style[self.GT_placement] = 0;
    }
    if (self.width) {
      style.width = `${self.width}px`;
    }
    if (self.height) {
      style.height = `${self.height}px`;
    }

    // 处理展开;
    if (self.GT_isExpand) {
      style[self.GT_placement] = 0;
    } else {
      // style[self.GT_placement] = self.width ? `${-self.width}px` : `${-self.height}px`;
      if (this.GT_position === 'left' || this.GT_position === 'right') {
        style[self.GT_placement] = `${-self.width}px`;
      } else {
        style[self.GT_placement] = `${-self.height}px`;
      }
    }

    self.$emit('expand', {
      name: self.GT_placement,
      isExpand: self.GT_isExpand,
      style
    });

    return style;
  }

  private boxStyle(): void {
    const L_position: string = this.position.toLowerCase();
    let L_err: boolean = false;
    switch (L_position) {
      case 'left':
        this.GT_mode = 'vertical';
        this.GT_position = 'right';
        this.GT_placement = 'left';
        break;
      case 'right':
        this.GT_mode = 'vertical';
        this.GT_position = 'left';
        this.GT_placement = 'right';
        break;
      case 'top':
        this.GT_mode = 'horizontal';
        this.GT_position = 'bottom';
        this.GT_placement = 'top';
        break;
      case 'bottom':
        this.GT_mode = 'horizontal';
        this.GT_position = 'top';
        this.GT_placement = 'bottom';
        break;

      default:
        console.error('Parameter [position] is incorrect');
        L_err = true;
        break;
    }
    if (!L_err) {
      this.GT_style = this.getStyle();
    }
  }

  public openCardBox() {
    this.toggleHandler(true);
  }

  public closeCardBox() {
    this.toggleHandler(false);
  }

  public toggleHandler(val: boolean = undefined) {
    if (this.disabled === true) {
      return;
    }
    this.GT_isExpand = val !== undefined ? val : !this.GT_isExpand;
    this.boxStyle();
    this.$emit('on-change', this.GT_isExpand);
  }
}
</script>
<style scoped lang="less" rel="stylesheet/less">
.card-box {
  display: inline-block;
  position: absolute;
  width: 100%;
  height: 100%;
  box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.1);
  background: var(--model-bg-color);
  // 后续整体调整系统层级时，严格测试（此时120）
  // z-index: 200;
  z-index: 102;
  transition: all 0.5s ease-in-out;

  .card-body {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 6px;
    // z-index: 2000;
    background: var(--model-bg-color);
    text-align: left;
    overflow-y: auto;
  }
}
</style>
